package cn.xiaolang.function.data_structure;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 启动 a,b 两个线程，由这两个线程打印出 1 到 100 共一百个数字。
 * 要求 a 线程打印 1、3、 5、7 等奇数，b 线程打印 2、4、6、8 等偶数。
 * 依次串行打印，即 打印完 1 之后，再打 印 2，然后是 3、4、5......直到 100
 *
 * @author fuhw/Dean
 * @date 2020-04-13
 */
@Slf4j
public class ThreadConcurrentVisibilityByWaitNotify {

    private static final AtomicInteger numbers = new AtomicInteger(1);

    private static final ReentrantLock LOCK = new ReentrantLock();
    private static final Condition connA = LOCK.newCondition();
    private static final Condition connB = LOCK.newCondition();

    /**
     * 锁加等待唤醒机制
     */
    public static void main(String[] args) {
        new Thread(() -> {
            LOCK.lock();
            try {
                while (numbers.get() <= 100) {
                    connB.signal();
                    log.info("{}", numbers.getAndIncrement());
                    connA.await(500, TimeUnit.MILLISECONDS);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                LOCK.unlock();
            }

        }, "A").start();

        new Thread(() -> {
            LOCK.lock();
            try {
                while (numbers.get() <= 100) {
                    connA.signal();
                    log.info("{}", numbers.getAndIncrement());
                    connB.await(500, TimeUnit.MILLISECONDS);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                LOCK.unlock();
            }

        }, "B").start();
    }


}
